// import { appendResponseHeader, H3Event } from 'h3'

import type { AsyncDataOptions } from "#app"
import { isMobile } from "~/utils"

interface IAsyncDataOptions extends AsyncDataOptions<{
    success: boolean,
    status: number,
    code: number,
    msg: string,
    data: any,
    exception?: any
}> {
    url?: string,
    method?: string,
    baseURL?: string,
    data?: string | object,
    body?: string | object,
    timeout?: number,
    headers?: Headers
}

interface IHeaders {
    Authorization?: string,
    'Unique-Visitor-Id'?: string,
    'User-Source'?: string,
    cookies?: string,
    [propName: string]: any,
}

const {
    VITE_API,
} = import.meta.env

const getFetchKey = (url: string) => url.replace(/\//g, '_')

const useMyHeaders = (_headers) => {
    const cookies = useRequestHeaders(['cookie'])
    console.log('cookies', cookies);
    const ua = useRequestHeaders(['user-agent'])?.['user-agent'] as string
    const userSource = isMobile(ua) ? 'wap' : 'pc'
    const headers: {
        'Plugin-Token'?: string,
        'Unique-Visitor-Id'?: string,
        'User-Source'?: string,
        'Plugin-Platform': string,
        cookies?: string,
    } = {
        ..._headers,
        ...cookies,
        'User-Source': userSource,
        'Plugin-Platform': 'website',
    }
    const uvid = useCookie("uuid")
    const token = useCookie("token")
    if (token.value) {
        headers['Plugin-Token'] = token.value
    }
    if (uvid.value) {
        headers['Unique-Visitor-Id'] = uvid.value
    }
    // console.log(headers)
    return headers
}

const useMyConfig = (conf: IAsyncDataOptions) => {
    // console.log('[useSSRFetch conf]:', conf)
    const {
        data,
        body,
        // timeout = 20 * 1000,
        timeout = 3,
        headers,
        baseURL: _baseURL,
        ...options
    } = conf || {}
    const _headers = useMyHeaders(headers)
    // console.log('[useSSRFetch baseURL]:', _baseURL || VITE_API)
    const rc: IAsyncDataOptions = {
        ...options,
        baseURL: _baseURL || VITE_API,
        headers: _headers
    }
    if (data || body) {
        rc.body = data || body
    }
    return rc
}

const useAbortController = (timeout = 20 * 1000) => {
    const abortInstance = new AbortController()
    const timer = setTimeout(() => abortInstance.abort(), timeout)
    const stopTimeout = () => clearTimeout(timer)
    return {
        abortInstance,
        stopTimeout
    }
}

export const useGain = async (options: IAsyncDataOptions) => {
    try {
        const {
            url,
            timeout = 20 * 1000,
            ...opts
        } = useMyConfig(options)
        // console.log('[useGain url]:', url)
        const conf = {
            ...opts,
            timeout,
        }
        // console.log('useGain conf:', conf)
        const respond = await $fetch(url, conf)
        // console.log('[useGain respond]:', respond)
        if (respond instanceof Blob) {
            return respond
        }
        const { success, data, code, msg } = respond
        if (success) {
            return respond
        }
        const err = {
            success,
            data,
            code,
            msg: msg || 'Unknown error'
        }
        if (code === 401) {
            err.msg = 'Log in has expired, Please login again'
            ElMessage
        }
        else if (code === 403) {
            err.msg = 'No permission to access this site'
        }
        else if (code === 404) {
            err.msg = 'Not found'
        }
        throw err
    } catch (error) {
        if (error?.message?.includes('aborted')) {
            error.msg = 'Request timeout!'
        }
        // console.log('[useGain error]:', error)
        return {
            success: false,
            code: 0,
            msg: error?.msg || error?.message
        }
    }
}

export const useSSRFetch = async (options: IAsyncDataOptions) => {
    const {
        url,
        timeout = 20 * 1000,
        ...opts
    } = useMyConfig(options)
    // console.log('[useSSRFetch url]:', url)
    const key = getFetchKey(url)
    const {
        abortInstance,
        stopTimeout
    } = useAbortController(timeout)
    const conf = {
        ...opts,
        server: true,
        key,
        signal: abortInstance.signal,
        onResponse() {
            stopTimeout()
        },
    }
    // console.log('useSSRFetch conf:', conf)
    const respond = await useFetch(url, conf)
    const { data, error, refresh } = respond
    // console.log('useSSRFetch error:', error.value)
    if (error.value || !data.value) {
        return respond
    }
    const success = data.value.success
    const result = ref(data.value.data)
    // console.log('useSSRFetch success:', success)
    if (success) {
        return {
            data: result,
            error,
            refresh
        }
    }
    return {
        data: null,
        error: data,
        refresh
    }
}
